#ifndef _H_PROCESS_SHAREFILE_H
#define _H_PROCESS_SHAREFILE_H
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <unistd.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/stat.h>
#include <thread>

typedef char s8;
typedef int s32;
typedef unsigned char u8;
typedef unsigned int u32;
#define FILEHANDLE s32
#define TZTEK_PROT_EXEC			0x1
#define TZTEK_PROT_READWRITE	0x2
#define TZTEK_MAP_SHARED		0x1
#define TZTEK_MAP_PRIVATED		0x2
#define TZTEK_MEMFD_INVALID_FILE -1
#define TZTEK_PROCESS_SHAREFILE_PATH "/tmp/memfd"

typedef struct tagTProcessShareHead
{
	volatile u32		dwMagic;	//魔幻数
	volatile u32		dwSumSize;	//总大小
	volatile u32		dwTailLen;	//环形缓存的拖尾长度
	volatile u32		dwRingLen;	//环形缓存大小	
	volatile u32		dwRidx;		//读指针
	volatile u32		dwWidx;		//写指针
	volatile u8			res[40];
}TProcessShareHead;


class CProcessShare
{
public:
	CProcessShare();
	~CProcessShare();
	//初始化
	bool Init(const s8* pFileName, u32 dwFileSize, const s8* pShareName, u32 dwMaxDataPacket, bool bProducer);
	//释放
	bool Release();
	//获取缓存
	bool GetBuf(u8*& pBuf, u32& dwBufLen);
	//获取数据
	bool GetData(u8*& pData, u32& dwDatalen);
	//存入数据
	bool InputData(u8* pData, u32 dwDataLen);
	bool InputData(u8* pData1, u32 dwDataLen1, u8* pData2, u32 dwDataLen2);
	//更新读索引
	bool UpdateReadIdx(u32 dwLen);
	//更新写索引
	bool UpdateWriteIdx(u32 dwLen);
	
	bool InitClient(void);

	bool InitServer(void);

private:
	int getSocket(const s8* pFileName);
    /*
	*@brief 初始化socket
	*@return
	*		-false	failed
	*		-true	succeed
	*/
    bool InitClientSocket(const s8* pFileName);
	bool InitServerSocket(const s8* pFileName);

	void send_fd(int socket, int fd, int n) ;
	int recv_fd(int socket);

    /*
        * @brief 带有超时的connect
        */
    int connectWithTimeOut(int fd, struct sockaddr *pAddr, unsigned int dwTimeOut);
	void *createPubSocketThread();
	void *createSubSocketThread();
protected:
	bool checkWritable(u32 dwLen);

private:
    u32             m_dwFileSize;
	s32				m_hFile;
	u8*				m_pBaseAddr;
	u8*				m_pDataAddr;
	TProcessShareHead* m_pProcessShareCtx;
	std::string     m_strFileName;
    s32             m_dwlistenFd;
	s32 m_fd;

	/* socket连接判断标志位 */
	s32 m_connectStatus;
	std::thread *m_pPubSocketThread;
	std::thread *m_pSubSocketThread;
	std::string m_strShareFileName;
	u32 m_dwMaxDataPacket;
	bool m_bflag;
	u32 m_dwErrorCnt;
	u32 m_dwSelectTimeout;
};

#endif


